/*
    Copyright 2007-2011 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/// \file
/// Implementation and explicit instantiations of the aux_grid_stage
/// class. \ingroup mcrx

// $Id$

#include "config.h"
#include "mcrx-stage.h"
#include "mcrx-stage-impl.h"
#include "create_grid.h"
#include "emergence-fits.h"
#include "grid-fits.h"
#include "arepo_grid.h"
#include "arepo_emission.h"


template <template <typename> class grid_type> 
bool 
mcrx::aux_grid_stage<grid_type>::check_stage_state () const
{
  bool state = false;
  try {
    this->output_file_->pHDU().readKey("MCRX" + stage_ID(), state);
  }
  catch (...) {}
  return state;
}

template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::set_stage_state (bool state)
{
  this->output_file_->pHDU().addKey("MCRX" + stage_ID(), state, "");
}




template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::setup_objects ()
{
  // Build grid/emission (they are the same) and 
  cout << "Building grid" << endl;

  T_grid* dummy=0;
  this->g_ = create_grid(*this->input_file_, dummy);
  this->emi_ = this->g_;

  // Build cameras based on -PARAMETERS HDUs in output file
  cout << "Setting up emergence" << endl;
  this->eme_.reset(new T_emergence (*this->output_file_));

  // no dust model is used
}


template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::load_file ()
{
  // first set up general stuff
  setup_objects();

  // Only thing to load is camera images
  this->eme_->load_images(*this->output_file_);
}


template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::load_dump (binifstream& dump_file)
{
  // first set up general stuff
  setup_objects();

  // Only thing to load is camera images
  this->eme_->load_dump(dump_file);
}


template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::save_file ()
{
  // Get normalization and save images
  const T_float normalization = this->emi_->total_emission_weight()/this->n_rays_;
  this->eme_->write_images(*this->output_file_, normalization, this->m_.units);
}


template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::save_dump (binofstream& dump_file) const
{
  this->eme_->write_dump(dump_file);
}


template <template <typename> class grid_type> 
bool mcrx::aux_grid_stage<grid_type>::shoot ()
{
  return this->shoot_nonscatter ();
}

template <template <typename> class grid_type> 
void mcrx::aux_grid_stage<grid_type>::operator() ()
{
  // this is here so the function is instantiated
  this->run_stage();
}


// explicit instantiations
template class mcrx::aux_grid_stage<mcrx::adaptive_grid>;

#ifdef WITH_AREPO
template class mcrx::aux_grid_stage<mcrx::arepo_grid>;
#endif
